#include "Startup.hpp"

#include "../common/definitions.h"

#define __COUNTING_DEP_DECL__
#include "AutoGenSupport.hpp"
//swarm_Dep_t dep;
RSTREAM_COUNTING_DEP_DECL(0, 7, 3)
#undef __COUNTING_DEP_DECL__

#define __TAG_TABLE_DECL__
#include "AutoGenSupport.hpp"
RSTREAM_TAG_TABLE_DECL(0, 7, 3)
#undef __TAG_TABLE_DECL__


#define __EDT_DEF__
#include "AutoGenSupport.hpp"
// swarm_CodeletDesc_IMPL_NOCANCEL_NOCAST(startup, startup, swarm_c_void, swarm_c_void)
RSTREAM_BEGIN_STARTUP_EDT_DEF(0, 7, 3)
#undef __EDT_DEF__

#define __TASK_TAG_GET__
#include "AutoGenSupport.hpp"
// const SwarmTagWrapper<SwarmTaskTag<0, 7, 3>> *tag_wrapper = 
//   SwarmTagWrapper<SwarmTaskTag<0, 7, 3> >::
//   _cast_fromAny((swarm_Any_i *)(void *)THIS);
// const SwarmTaskTag<0, 7, 3> &tag = *(tag_wrapper->tInst);
RSTREAM_TASK_TAG_GET(foo, tag_ptr, 0, 7, 3)
#undef __TASK_TAG_GET__
local_tag_t tag = tag_ptr;



// Init tag table related to problem size 
// swarm_TagTable_init(&polySwarmTaskTags, 1023);  
#define __TAG_TABLE_INIT__
#include "AutoGenSupport.hpp"
RSTREAM_TAG_TABLE_INIT(0, 7, 3, 255)
#undef __TAG_TABLE_INIT__

int64_t pT = tag[0+3];
int64_t pM = tag[1+3];
int64_t pN = tag[2+3];
int64_t pP = tag[3+3];

// std::cerr << "Starting Spawn " << pT << " " << pN << " " << pM << " " << pP << "\n";

{ // Auto-generated polyhedral loops
  int64_t t1, t2, t3;

  int global_counter = 0;
  for (t1=ceild(-pN-15,16);t1<=floord(pT-3,16);t1++) {
    for (t2=max(t1,-t1-1);
	 t2<=min(min(floord(-8*t1+pT-2,8),floord(8*t1+pN+7,8)),floord(pT+pN-2,16));t2++) {
      // // Bulk 
      // global_counter +=
      //   min(min(floord(pT+pN-2,16),floord(16*t2+pN+14,16)),floord(8*t1+8*t2+pN+15,16))
      //   - max(max(0,ceild(t1+t2-1,2)),ceild(16*t2-pN-14,16)) + 1;
      // Bulk 
      for (t3=max(max(0,ceild(t1+t2-1,2)),ceild(16*t2-pN-14,16));
	   t3<=min(min(floord(pT+pN-2,16),floord(16*t2+pN+14,16)),floord(8*t1+8*t2+pN+15,16));
	   t3++) {
        global_counter++;
      }
    }
  }

  // Create a dependence whose continuation is NEXT, NEXT_THIS
  // Initialize to global_counter
#define __COUNTING_DEP_INIT__
#include "AutoGenSupport.hpp"
  // swarm_Dep_init(&dep, global_counter, &CODELET(shutdown), NULL, NULL);
  // RSTREAM_COUNTING_DEP_INIT(0, 7, 3, global_counter, &CODELET(shutdown))
  RSTREAM_COUNTING_DEP_INIT(0, 7, 3, global_counter)
#undef __COUNTING_DEP_INIT__

  for (t1=ceild(-pN-15,16);t1<=floord(pT-3,16);t1++) {
    for (t2=max(t1,-t1-1);
	 t2<=min(min(floord(-8*t1+pT-2,8),floord(8*t1+pN+7,8)),floord(pT+pN-2,16));t2++) {
      // Bulk 
      for (t3=max(max(0,ceild(t1+t2-1,2)),ceild(16*t2-pN-14,16));
	   t3<=min(min(floord(pT+pN-2,16),floord(16*t2+pN+14,16)),floord(8*t1+8*t2+pN+15,16));
	   t3++) {        

	// SwarmTaskTag<0, 7, 3> *t = new SwarmTaskTag<0, 7, 3> 
	//   (static_cast<tag_elem_t>(t1),  static_cast<tag_elem_t>(t2),  
	//    static_cast<tag_elem_t>(t3),  static_cast<tag_elem_t>(pT),  
	//    static_cast<tag_elem_t>(pM),  static_cast<tag_elem_t>(pN),  
	//    static_cast<tag_elem_t>(pP));
        // SwarmTagWrapper<SwarmTaskTag<0, 7, 3> > *stw = 
        //   new SwarmTagWrapper<SwarmTaskTag<0, 7, 3> > (t);
	// // Spawn codelet corresponding to t.
	// swarm_schedule(&swarm_CodeletDesc_CODELET(heat3d), stw, NULL, NULL, NULL);

//           {
// #define __TASK_TAG_INIT__
// #define __TASK_SCHEDULE__
// #include "AutoGenSupport.hpp"
//             RSTREAM_TASK_TAG_INIT(local, 0, 7, 3, 
//                                   (tag_elem_t)t1, (tag_elem_t)t2, (tag_elem_t)t3,
//                                   (tag_elem_t)pT, (tag_elem_t)pM, (tag_elem_t)pN,
//                                   (tag_elem_t)pP);
//             RSTREAM_TASK_SCHEDULE(local, 0, 7, 3);
// #undef __TASK_SCHEDULE__
// #undef __TASK_TAG_INIT__
//           }

          {
#define __TASK_TAG_INIT_AND_SCHEDULE__
#include "AutoGenSupport.hpp"
            RSTREAM_TASK_TAG_INIT_AND_SCHEDULE(0, 7, 3, 
                                               (tag_elem_t)t1, (tag_elem_t)t2, (tag_elem_t)t3,
                                               (tag_elem_t)pT, (tag_elem_t)pM, (tag_elem_t)pN,
                                               (tag_elem_t)pP);
#undef __TASK_TAG_INIT_AND_SCHEDULE__
          }

      }
    }
  }  
}
#define __EDT_DEF__
#include "AutoGenSupport.hpp"
// swarm_CodeletDesc_IMPL_END;
RSTREAM_END_STARTUP_EDT_DEF(0, 7, 3)
#undef __EDT_DEF__
